#include "Ball.h"
#include "../SGD Wrappers/SGD_GraphicsManager.h"
#include "../tile/TileManager.h"
#include "../Game.h"
#include "Agent.h"
#include "Wall.h"
#include "Runner.h"
CBall::CBall()

{

	Listener::RegisterForEvent("TORNADO_SWIRL");
}


CBall::~CBall()
{
	Listener::UnregisterFromEvent("TORNADO_SWIRL");
}

void CBall::Render(void)
{
	if (m_bAerial == true)
		SGD::GraphicsManager::GetInstance()->DrawRectangle({ SGD::Point{ (m_ptShadowPos.x - Game::GetInstance()->GetCameraPos().x - 15), (m_ptShadowPos.y - Game::GetInstance()->GetCameraPos().y - 15) },
			
		m_szSize * 2 }, SGD::Color{ 255, 175, 0 }, { 0, 0, 0 }, 3);
	else
		SGD::GraphicsManager::GetInstance()->DrawRectangle({ SGD::Point{ (m_ptPosition.x - Game::GetInstance()->GetCameraPos().x - 15), (m_ptPosition.y - Game::GetInstance()->GetCameraPos().y - 15) },
			
		m_szSize * 2 }, SGD::Color{ 255, 175, 0 }, { 0, 0, 0 }, 3);

	SGD::GraphicsManager::GetInstance()->DrawRectangle({ SGD::Point{ (m_ptPosition.x - Game::GetInstance()->GetCameraPos().x), (m_ptPosition.y - Game::GetInstance()->GetCameraPos().y) },
			
		m_szSize }, SGD::Color{ 0, 255, 0 }, { 0, 0, 0 }, 3);


}

void CBall::Update(float elapsedTime) /*override*/
{
	if (m_bMiniGame)
	{
		if (explosion == false)
		{

			if (this->m_bIsHeld == false && this->m_bAerial == false && spawn == false)
			{
				bombtimer -= elapsedTime;
			}
			if (bombtimer <= 0.0f && explosion == false)
			{
				Explosion();
			}
		}
		else
			ToggleActive(false);
	}

	CTileManager::GetInstance()->BallCollision(this->GetRect(), this);

	Entity::Update(elapsedTime);
}

void CBall::Rebound()
{

}

/*virtual*/ void CBall::HandleCollision(const Entity* pOther)	/*override*/
{
	if (pOther->GetType() == ENT_PLAYER)
	{
		if (m_bMiniGame)
		{
			if (dynamic_cast<const CAgent*>(pOther)->GetIsExhausted() == false && m_bAerial == false)
			{
				m_bIsHeld = true;
				this->spawn = false;
				this->SetTimer(8.0f);
				ToggleActive(false);
			}

			else if (pOther->CheckActive() == true && this->GetOwner() != reinterpret_cast<const CPlayer*>(pOther) && explosion == false)
				Explosion();
		}

		Entity* player = const_cast<Entity*>(pOther);
		if (dynamic_cast<const CAgent*>(pOther)->GetIsExhausted() == false && m_bAerial == false && m_nPowerLevel == 0 
			&& dynamic_cast<CPlayer*>(player)->GetBeingCarried() == false && dynamic_cast<CPlayer*>(player)->GetCarryDude() == nullptr &&
			dynamic_cast<CPlayer*>(player)->GetBall() == this)
		{
			m_bIsHeld = true;
			ToggleActive(false);
		}
	}

	Entity* wall = const_cast<Entity*>(pOther);

	if (pOther->GetType() == ENT_WALL && (dynamic_cast<CWall*>(wall)->GetImpenetrable() == true || dynamic_cast<CWall*>(wall)->GetHeight() == true))
	{
		
		SGD::Rectangle rIntersect = pOther->GetRect().ComputeIntersection(GetRect());
		if (rIntersect.ComputeHeight() <= rIntersect.ComputeWidth())
		{
			
			if (GetRect().top == rIntersect.top)
				m_ptPosition.y = pOther->GetPosition().y + pOther->GetSize().height;
			else
				m_ptPosition.y = pOther->GetPosition().y - m_szSize.height;
		}
		
		else if (rIntersect.ComputeHeight() >= rIntersect.ComputeWidth())
		{
			
			if (GetRect().left == rIntersect.left)
				m_ptPosition.x = pOther->GetPosition().x + pOther->GetSize().width;
			else
				m_ptPosition.x = pOther->GetPosition().x - m_szSize.width;
		}
		m_bAerial = false;
		m_vtVelocity = { 0, 0 };
	}

	if (pOther->GetType() == ENT_WALL && dynamic_cast<CWall*>(wall)->GetImpenetrable() == false && m_nPowerLevel != 0)
		wall->ToggleActive(false);
}

void CBall::HandleEvent(const SGD::Event* pEvent) /*override*/
{

	if (pEvent->GetEventID() == "TORNADO_SWIRL")
	{
		if (pEvent->GetSender() != this)
		{

			switch (reinterpret_cast<int>(pEvent->GetData()))
			{
			case 1:
			{
					  if (this->m_ptPosition.x < reinterpret_cast<CRunner*>(pEvent->GetSender())->GetTornadoPos().x)
					  this->m_vtVelocity.x = 10;
					  else
					  {
						  this->m_vtVelocity.x = -10;
					  }


					  if (this->m_ptPosition.y < reinterpret_cast<CRunner*>(pEvent->GetSender())->GetTornadoPos().y)
						  this->m_vtVelocity.y = 10;
					  else
					  {
						  this->m_vtVelocity.y = -10;
					  }

					 
			}
				break;
			case 2:
			{
					  if (this->m_ptPosition.x < reinterpret_cast<CRunner*>(pEvent->GetSender())->GetTornadoPos().x)
						  this->m_vtVelocity.x = 100;
					  else
					  {
						  this->m_vtVelocity.x = -100;
					  }


					  if (this->m_ptPosition.y < reinterpret_cast<CRunner*>(pEvent->GetSender())->GetTornadoPos().y)
						  this->m_vtVelocity.y = 100;
					  else
					  {
						  this->m_vtVelocity.y = -100;
					  }
			}
				break;
			case 3:
			{
					  if (this->m_ptPosition.x < reinterpret_cast<CRunner*>(pEvent->GetSender())->GetTornadoPos().x)
						  this->m_vtVelocity.x = 200;
					  else
					  {
						  this->m_vtVelocity.x = -200;
					  }


					  if (this->m_ptPosition.y < reinterpret_cast<CRunner*>(pEvent->GetSender())->GetTornadoPos().y)
						  this->m_vtVelocity.y = 200;
					  else
					  {
						  this->m_vtVelocity.y = -200;
					  }
			}
				break;
			default:
				break;
			}
		}
	}
	if (reinterpret_cast<CRunner*>(pEvent->GetSender())->GetTornadoTimer() <= 0.1f)
		this->SetVelocity({0,0});
}

void CBall::Explosion()
{
	explosion = true;
	this->m_ptPosition.x -= 16;
	this->m_ptPosition.y -= 16;
	this->m_szSize.height += 16;
	this->m_szSize.width += 16;
}
